package com.example.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.entity.Employee;
import com.example.entity.Salary;
import com.example.entity.SalaryImport;
import com.example.exception.CustomException;
import com.example.mapper.EmployeeMapper;
import com.example.mapper.SalaryMapper;
import com.example.service.SalaryService;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 薪资导入Excel监听器
 * SalaryImportListener 类用于从 Excel 文件中导入薪资数据，并进行必要的数据校验和保存操作。
 */
public class SalaryImportListener extends AnalysisEventListener<SalaryImport> {

    private final EmployeeMapper employeeMapper;
    private final SalaryMapper salaryMapper;
    private final SalaryService salaryService;
    
    // 批处理阈值
    private static final int BATCH_COUNT = 100;
    // 存储读取的数据
    private final List<SalaryImport> dataList = new ArrayList<>();
    // 导入结果统计
    private int totalCount = 0;
    private int successCount = 0;
    private int failCount = 0;
    private final List<String> errorMessages = new ArrayList<>();

    public SalaryImportListener(EmployeeMapper employeeMapper, SalaryMapper salaryMapper, SalaryService salaryService) {
        this.employeeMapper = employeeMapper;
        this.salaryMapper = salaryMapper;
        this.salaryService = salaryService;
    }

    @Override
    public void invoke(SalaryImport data, AnalysisContext context) {
        totalCount++;
        dataList.add(data);
        // 达到BATCH_COUNT，需要批量处理一次，防止数据几万条时内存溢出
        if (dataList.size() >= BATCH_COUNT) {
            saveData();
            // 清理，方便GC回收
            dataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 确保最后遗留的数据也被处理
        saveData();
    }

    private void saveData() {
        for (SalaryImport salaryImport : dataList) {
            try {
                // 数据校验
                if (!StringUtils.hasText(salaryImport.getEmployeeName())) {
                    throw new CustomException("400", "员工姓名不能为空");
                }
                if (!StringUtils.hasText(salaryImport.getSalaryMonth())) {
                    throw new CustomException("400", "薪资月份不能为空");
                }
                if (!salaryImport.getSalaryMonth().matches("\\d{4}-\\d{2}")) {
                    throw new CustomException("400", "薪资月份格式不正确，应为yyyy-MM");
                }
                
                // 查询员工信息
                Employee queryEmployee = new Employee();
                queryEmployee.setName(salaryImport.getEmployeeName());
                List<Employee> employees = employeeMapper.selectAll(queryEmployee);
                if (employees.isEmpty()) {
                    throw new CustomException("400", "员工 " + salaryImport.getEmployeeName() + " 不存在");
                }
                if (employees.size() > 1) {
                    throw new CustomException("400", "存在多个同名员工 " + salaryImport.getEmployeeName() + "，请确认");
                }
                
                Employee employee = employees.get(0);
                
                // 检查是否已存在该员工当月薪资记录
                Salary existSalary = salaryMapper.selectByEmployeeIdAndMonth(employee.getId(), salaryImport.getSalaryMonth());
                if (existSalary != null) {
                    throw new CustomException("400", "员工 " + salaryImport.getEmployeeName() + " 的 " + salaryImport.getSalaryMonth() + " 薪资记录已存在");
                }
                
                // 创建薪资记录
                Salary salary = new Salary();
                salary.setEmployeeId(employee.getId());
                salary.setSalaryMonth(salaryImport.getSalaryMonth());
                salary.setBaseSalary(salaryImport.getBaseSalary() != null ? salaryImport.getBaseSalary() : BigDecimal.ZERO);
                salary.setPerformance(salaryImport.getPerformance() != null ? salaryImport.getPerformance() : BigDecimal.ZERO);
                salary.setBonus(salaryImport.getBonus() != null ? salaryImport.getBonus() : BigDecimal.ZERO);
                salary.setDeduction(salaryImport.getDeduction() != null ? salaryImport.getDeduction() : BigDecimal.ZERO);
                
                // 设置状态，默认为待发放
                String status = salaryImport.getStatus();
                if (!StringUtils.hasText(status) || (!"PENDING".equals(status) && !"PAID".equals(status))) {
                    status = "PENDING";
                }
                salary.setStatus(status);
                
                // 计算实发工资
                salaryService.calculateActualSalary(salary);
                
                // 保存薪资记录
                salaryMapper.insert(salary);
                
                successCount++;
            } // 在catch块中
            catch (Exception e) {
                failCount++;
                // 针对CustomException特殊处理
                String errorMsg;
                if (e instanceof CustomException) {
                    errorMsg = ((CustomException) e).getMsg();
                } else {
                    errorMsg = e.getMessage();
                    if (errorMsg == null) {
                        errorMsg = "未知错误: " + e.getClass().getSimpleName();
                    }
                }
                errorMessages.add("第" + totalCount + "行: " + errorMsg);
            }
        }
    }

    public int getTotalCount() {
        return totalCount;
    }

    public int getSuccessCount() {
        return successCount;
    }

    public int getFailCount() {
        return failCount;
    }

    public List<String> getErrorMessages() {
        return errorMessages;
    }
}